home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / human interface toolbox / setindstring / setindstring.c
Encoding:
Text File  |  2000-06-23  |  3.8 KB  |  124 lines

  1. /*
  2.     File:        SetIndString.c
  3.  
  4.     Contains:    I have been reviewing your question on how to set the contents of STR# resources
  5.                 from your program.
  6.  
  7.                 As it turns out, there is no Toolbox call to do this, mostly because resources are
  8.                 not meant to store data which changes frequently.  I have a solution to your
  9.                 problem, but it comes with a warning: PLEASE DON'T CHANGE ANY OF YOUR APPLICATIONS
  10.                 RESOURCES WHILE RUNNING.  Doing so will make it impossible for your program to run
  11.                 off of a fileserver or locked volume.
  12.  
  13.                 That out of the way the format of an STR# resource is:
  14.  
  15.                 2 bytes       number of strings
  16.                 -------------------------------
  17.                 1 byte        length of 1st str
  18.                 (variable)    1st string data
  19.                 -------------------------------
  20.                 1 byte        length of nth str
  21.                 (variable)    nth string data
  22.                 ...
  23.                 ...
  24.  
  25.                 Note that the indexes into the strings are not at set positions, but instead are
  26.                 relative to the lengths of the previous strings.
  27.  
  28.                 Finally, here's a C function, SetIndString() which takes the same parameters as
  29.                 GetIndString().  This call does the opposite, namely, it sets a particular STR#
  30.                 string to the passed in string:
  31.                 
  32.     Written by:     
  33.  
  34.     Copyright:    Copyright © 1984-1999 by Apple Computer, Inc., All Rights Reserved.
  35.  
  36.                 You may incorporate this Apple sample source code into your program(s) without
  37.                 restriction. This Apple sample source code has been provided "AS IS" and the
  38.                 responsibility for its operation is yours. You are not permitted to redistribute
  39.                 this Apple sample source code as "Apple sample source code" after having made
  40.                 changes. If you're going to re-distribute the source, we require that you make
  41.                 it clear in the source that the code was descended from Apple sample source
  42.                 code, but that you've made changes.
  43.  
  44.     Change History (most recent first):
  45.                 8/9/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  46.                 
  47.  
  48. */
  49.  
  50. OSErr SetIndString(StringPtr theStr,short resID,short strIndex)
  51. {
  52.    Handle theRes;               /* handle pointing to STR# resource */
  53.    short numStrings;            /* number of strings in STR# */
  54.    short ourString;             /* counter to index up to strIndex */
  55.    char *resStr;                /* string pointer to STR# string to replace */
  56.    long oldSize;                /* size of STR# resource before call */
  57.    long newSize;                /* size of STR# resource after call */
  58.    unsigned long offset;        /* resource offset to str to replace*/
  59.  
  60.    /* make sure index is in bounds */
  61.  
  62.    if (resID < 1)
  63.    return -1;
  64.  
  65.    /* make sure resource exists */
  66.  
  67.    theRes = GetResource('STR#',resID);
  68.    if (ResError()!=noErr)
  69.    return ResError();
  70.    if (!theRes || !(*theRes))
  71.    return resNotFound;
  72.  
  73.    HLock(theRes);
  74.    HNoPurge(theRes);
  75.  
  76.    /* get # of strings in STR# */
  77.  
  78.    BlockMove(*theRes,&numStrings,sizeof(short));
  79.    if (strIndex > numStrings)
  80.    return resNotFound;
  81.  
  82.    /* get a pointer to the string to replace */
  83.  
  84.    offset = sizeof(short);
  85.    resStr = (char *) *theRes + sizeof(short);
  86.    for (ourString=1; ourString<strIndex; ourString++) {
  87.    offset += 1+resStr[0];
  88.    resStr += 1+resStr[0];
  89.    }
  90.  
  91.    /* grow/shrink resource handle to make room for new string */
  92.  
  93.    oldSize = GetHandleSize(theRes);
  94.    newSize = oldSize - resStr[0] + theStr[0];
  95.    HUnlock(theRes);
  96.    SetHandleSize(theRes,newSize);
  97.    if (MemError()!=noErr) {
  98.    ReleaseResource(theRes);
  99.    return -1;
  100.    }
  101.    HLock(theRes);
  102.    resStr = *theRes + offset;
  103.  
  104.    /* move old data forward/backward to make room */
  105.  
  106.    BlockMove(resStr+resStr[0]+1, resStr+theStr[0]+1, oldSize-offset-resStr[0]-1
  107.  
  108.    /* move new data in */
  109.  
  110.    BlockMove(theStr,resStr,theStr[0]+1);
  111.  
  112.    /* write resource out */
  113.  
  114.    ChangedResource(theRes);
  115.    WriteResource(theRes);
  116.    HPurge(theRes);
  117.    ReleaseResource(theRes);
  118.  
  119.    return ResError();
  120. }
  121.  
  122. ----------
  123.  
  124.